﻿using System;
using System.Html.DOM;

using Mojo.Widgets;

namespace Mojo
{
    public class SceneController
    {
        public readonly Document document;

        public readonly AbstractSceneAssistant Assistant;

        public StageController StageController;

        public void SetDefaultTransition(Transition transitionType)
        {
        }

        public bool IsActive()
        {
            return false;
        }

        /// <summary>
        /// Returns elements of this scene that match the given CSS selector. Uses native querySelectorAll function.
        /// </summary>
        /// <param name="cssSelector"></param>
        /// <returns></returns>
        public HtmlElement[] Select(string cssSelector)
        {
            return null;
        }

        /// <summary>
        /// Adds the given commander to the top of this SceneController's stack.
        ///  The commanders in this stack are only used when this scene is the current scene.
        /// </summary>
        /// <param name="cmdr"></param>
        public void PushCommander(object cmdr)
        {
        }

        public void RemoveCommander(object cmdr)
        {
        }

        /// <summary>
        /// Register the given attributes and model to be used with the widget of the given name.
        /// Called by scene assistants in their `setup()` methods.
        /// If a model is specified here for a widget that is rendered in a list item, the model
        /// will be overridden by the one for the list item.
        /// </summary>
        /// <param name="name">Widget element id or name</param>
        /// <param name="attributes">Widget's attributes object</param>
        /// <param name="model">Widget's model object</param>
        public void SetupWidget(string name, WidgetsCreateAttributes attributes, WidgetsCreateModel model)
        {
        }        

        /// <summary>
        /// Sets the model for a widget, and notifies the widget of the new model.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="model"></param>
        public void SetWidgetModel(string id, object model)
        {
        }

        /// <summary>
        /// Sets the model for a widget, and notifies the widget of the new model.
        /// </summary>
        /// <param name="widget"></param>
        /// <param name="model"></param>
        public void SetWidgetModel(HtmlElement widget, object model)
        {
        }

        /// <summary>
        /// Scene assistants can call this method when their data changes and a 
        /// widget displaying that data needs to be updated. Changes might include, for example,
        /// added or removed an element, modified one or more properties of an element, etc.
        /// </summary>
        /// <param name="model">Model object that changed</param>
        public void ModelChanged(object model)
        {
        }

        /// <summary>
        /// Scene assistants can call this method when their data changes and a 
        /// widget displaying that data needs to be updated. Changes might include, for example,
        /// added or removed an element, modified one or more properties of an element, etc.
        /// </summary>
        /// <param name="model">Model object that changed</param>
        /// <param name="who">The object owning the changeFunc, used to ensure that
        ///	objects are not notified of their own changes to the model.
        ///	</param>
        public void ModelChanged(object model, object who)
        {
        }

        /// <summary>
        /// Sign up for change notifications for the given model. When someone calls 
        /// modelChanged with the model of interest, the `changeFunc` will be called. Usually 
        /// used by the framework to notify widgets when their models change.
        /// </summary>
        /// <param name="model">Model object.</param>
        /// <param name="who">The object owning the changeFunc, used to ensure that	objects are not notified of their own changes to the model.</param>
        /// <param name="changeFunc">Function called when modelChanged with the model of interest, in the context of 'who'.</param>
        public void WatchModel(object model, object who, Delegate changeFunc)
        {
        }

        /// <summary>
        /// Remove a "model watch" for the given watcher.  If 'model' is undefined, then all registered "model watches" for the given watcher are removed.
        /// </summary>
        /// <param name="watcher">The object owning the changeFunc, when watchModel was called.</param>
        /// <param name="model">Model object, or left undefined all registered "model watches" for the given watcher are removed.</param>
        public void RemoveWatcher(object watcher, object model)
        {
        }


        /// <summary>
        /// Enables and disables receiving 'page up' and 'page down' key events in
        ///	response to the "swipe" gesture when the scene is in landscape mode, 
        /// instead of the "back" signal.  This property is persistent for each
        /// scene, so it is not necessary for client code to manage it.
        /// </summary>
        /// <param name="yesNo"></param>
        public void UseLandscapePageUpDown(bool yesNo)
        {
        }

        /// <summary>
        /// Enables and disables full screen mode for the scene.  This property is
        /// persistent for each scene, so it is not necessary for client code to
        /// manage it.
        /// </summary>
        /// <param name="yesNo"></param>
        public void EnableFullScreenMode(bool yesNo)
        {
        }

        /// <summary>
        /// Makes the view or command menu either visible or hidden.
        /// </summary>
        /// <param name="which">Menu name; either  Mojo.Menu.viewMenu or Mojo.Menu.commandMenu</param>
        /// <param name="visible"></param>
        public void SetMenuVisible(string which, bool visible)
        {
        }

        /// <summary>
        /// Returns the visibility state of either the view or command menu.
        /// </summary>
        /// <param name="which">Menu name; either  Mojo.Menu.viewMenu or Mojo.Menu.commandMenu</param>
        /// <returns></returns>
        public bool GetMenuVisible(string which)
        {
            return false;
        }

        /// <summary>
        /// Menu name; either  Mojo.Menu.viewMenu or Mojo.Menu.commandMenu.
        /// </summary>
        /// <param name="which"></param>
        public void ToggleMenuVisible(string which)
        {
        }

        /// <summary>
        /// Remove a request from the scene's list of requests to manage. A removed request will not
        /// be cancelled when the scene is popped, and unless another reference is kept to the request
        /// it can be garbage collected (and thus cancelled) at any time.
        /// </summary>
        /// <param name="request"></param>
        public void RemoveRequest(Mojo.Service.Request request)
        {
        }
       
        /// <summary>
        /// Cancels and removes a service request. This request must have been 
        /// created with the scene controller's serviceRequest method.
        /// </summary>
        /// <param name="request"></param>
        public void CancelServiceRequest(Mojo.Service.Request request)
        {
        }
        
        /// <summary>
        /// Creates a Palm service request which will be automatically cancelled when 
        /// the scene is popped. The parameters are passed directly to new Mojo.Service.Request().
        /// </summary>
        /// <param name="url"></param>
        /// <param name="optionsIn"></param>
        /// <returns></returns>
        public Mojo.Service.Request ServiceRequest(string url, object optionsIn)
        {
            return null;
        }        

        /// <summary>
        /// Creates a Palm service request which will be automatically cancelled when 
        /// the scene is popped. The parameters are passed directly to new Mojo.Service.Request().
        /// </summary>
        /// <param name="url"></param>
        /// <param name="optionsIn"></param>
        /// <param name="resubscribe">
        /// Set to 'true' to automatically resubscribe when receiving an error from the service
        /// </param>
        /// <returns></returns>
        public Mojo.Service.Request ServiceRequest(string url, object optionsIn, bool resubscribe)
        {
            return null;
        }
        
        public MojoElement Get(string elementId)
        {
            return null;
        }

        public MojoElement<TWidget> Get<TWidget>(string elementId)
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="elementId"></param>
        /// <param name="eventType">eventType String identifier for the event type.</param>
        /// <param name="callback">callback Function object that was registered to be called when the event occurred.</param>
        /// <param name="onCapture">(optional) Pass true to listen during the capture phase, false to listen during bubbling.</param>
        public void Listen(string elementId, string eventType, Delegate callback, bool onCapture)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="element"></param>
        /// <param name="eventType">eventType String identifier for the event type.</param>
        /// <param name="callback">callback Function object that was registered to be called when the event occurred.</param>
        /// <param name="onCapture">(optional) Pass true to listen during the capture phase, false to listen during bubbling.</param>
        public void Listen(HtmlElement element, string eventType, Delegate callback, bool onCapture)
        {
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="elementId"></param>
        /// <param name="eventType">eventType String identifier for the event type.</param>
        /// <param name="callback">callback Function object that was registered to be called when the event occurred.</param>
        /// <param name="onCapture">(optional) Pass true to listen during the capture phase, false to listen during bubbling.</param>
        public void StopListening(string elementId, string eventType, Delegate callback, bool onCapture)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="element"></param>
        /// <param name="eventType">eventType String identifier for the event type.</param>
        /// <param name="callback">callback Function object that was registered to be called when the event occurred.</param>
        /// <param name="onCapture">(optional) Pass true to listen during the capture phase, false to listen during bubbling.</param>
        public void StopListening(HtmlElement element, string eventType, Delegate callback, bool onCapture)
        {
        }
        
        /// <summary>
        /// </summary>
        /// <param name="initialFocusedElement">Pass null to prevent automatic focus</param>
        public void SetInitialFocusedElement(string elementId)
        {
        }

        /// <summary>
        /// </summary>
        /// <param name="element">Pass null to prevent automatic focus</param>
        public void SetInitialFocusedElement(HtmlElement element)
        {
        }

        /// <summary>
        /// Utility function to tell listening widgets to commit themselves
        /// </summary>
        public void CommitChanges()
        {
        }
    }
}
